# Please install OpenAI SDK first: `pip3 install openai`
from io import BytesIO
from tkinter import Canvas
from fastapi import APIRouter, BackgroundTasks, Depends, File, UploadFile, HTTPException, requests, status
from fastapi.responses import FileResponse, StreamingResponse
from fastapi.security import HTTPBearer
from openai import OpenAI
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from app.dependencies import get_current_user, require_role
from app.models.user import UserRole
from app.schemas.user import UserOccupied
from pathlib import Path
from openai import OpenAI
from reportlab.pdfgen import canvas
from werkzeug.utils import secure_filename
from reportlab.lib.pagesizes import letter
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
import re
import pdfplumber
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
router = APIRouter()



@router.post("/advice", summary="获取求职建议")
async def get_advice(
    content: str,
    current_user: UserOccupied = Depends(get_current_user),
    _=Depends(require_role([UserRole.JOB_SEEKER]))
):
    """
    获取AI求职建议
    
    权限要求:
    - 需要求职者权限
    
    参数:
    - content: str, 用户输入的内容
    - current_user: UserOccupied, 当前登录用户信息
    
    返回:
    - dict: 包含AI建议的响应
    
    异常:
    - 500 Internal Server Error: 如果AI服务调用失败时抛出
    """
	    #访问接口进行身份验证
    client = OpenAI(api_key="sk-4e7efad16e6c45b8aa38a8a2c2ce34dd", base_url="https://api.deepseek.com")
    try:
        response = client.chat.completions.create(
            model="deepseek-chat",
            messages=[
                {"role": "system", "content": "你是一个有丰富经验的hr,请对求职者给出建议。"},
                {"role": "user", "content": content},
            ],
            stream=False
        )
        return {"advice": response.choices[0].message.content}
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"获取建议失败: {str(e)}"
        )



 
# 注册中文字体（需要实际字体文件路径）
try:
    pdfmetrics.registerFont(TTFont('SimSun', 'C:\\Windows\\Fonts\\simsun.ttc'))  # 使用正确的字体路径和名称
except:
    pdfmetrics.registerFont(TTFont('SimSun', '/usr/share/fonts/truetype/simsun.ttc'))  # Linux备用路径

def validate_extension(filename: str) -> bool:
    """更可靠的文件扩展名验证"""
    allowed_ext = {'.pdf', '.doc', '.docx'}
    file_ext = Path(filename).suffix.lower()
    return file_ext in allowed_ext

async def cleanup_file(path: Path):
    if path.exists():
        path.unlink()

def validate_file_content(content: bytes, filename: str) -> bool:
    """增强版文件内容验证"""
    try:
        # 优先使用pdfplumber验证PDF内容
        if filename.lower().endswith('.pdf'):
            with pdfplumber.open(BytesIO(content)) as pdf:
                if len(pdf.pages) == 0:
                    return False
                text = pdf.pages[0].extract_text()
                return text and len(text.strip()) > 50
        # 处理Word文档（需要实际解析逻辑）
        else:  
            return len(content) > 4096  # 简单验证文件大小
    except Exception as e:
        raise ValueError(f"文件内容验证失败: {str(e)}")

def generate_professional_pdf(text: str, filename: Path):
    """生成专业排版的PDF"""
    styles = getSampleStyleSheet()
    styles.add(ParagraphStyle(
        'ResumeStyle',
        fontName='SimSun',
        fontSize=12,
        leading=14
    ))
    
    doc = SimpleDocTemplate(str(filename), pagesize=letter)  # Convert Path to string
    elements = []
    
    # 预处理文本，移除可能包含HTML标签的内容
    clean_text = re.sub(r'<[^>]+>', '', text)  # 移除HTML标签
    
    for line in clean_text.split('\n'):
        if line.strip():
            p = Paragraph(line, styles['ResumeStyle'])
            elements.append(p)
            elements.append(Spacer(1, 12))
    
    doc.build(elements)

@router.post("/optimize_resume", summary="优化简历")
async def optimize_resume(
    file: UploadFile = File(...),
    current_user: UserOccupied = Depends(get_current_user),
    background_tasks: BackgroundTasks = BackgroundTasks(),
    _=Depends(require_role([UserRole.JOB_SEEKER]))
):
    # 安全处理文件名并验证类型
    filename = secure_filename(file.filename)
    if not validate_extension(filename):
        raise HTTPException(
            status_code=400,
            detail="仅支持PDF/DOC/DOCX格式 (Supported: .pdf .doc .docx)"
        )
    
    temp_dir = Path("temp_resumes")
    temp_dir.mkdir(exist_ok=True)
    temp_path = temp_dir / f"temp_{current_user.id}_{filename}"
    # Remove duplicate .pdf extension if original is already PDF
    output_filename = f"optimized_{Path(filename).stem}.pdf"
    optimized_path = temp_dir / f"optimized_{current_user.id}_{output_filename}"

    try:
        # 读取并验证文件内容
        file_content = await file.read()
        if not validate_file_content(file_content, filename):
            raise HTTPException(400, "文件内容不可读或为空")

        # 保存临时文件
        temp_path.write_bytes(file_content)
        
        # 初始化OpenAI客户端
        client = OpenAI(
            api_key="sk-A8HJvTk0nP5n9NP9wO9kqTPmSDD28nES787D8rU3wcAULC4S",
            base_url="https://api.moonshot.cn/v1",
        )
        
        # 上传文件并调用模型处理
        with temp_path.open('rb') as f:
            uploaded_file = client.files.create(file=f, purpose="file-extract")
        
        completion = client.chat.completions.create(
            model="moonshot-v1-8k",
            messages=[
                {
                    "role": "system",
                    "content": "作为专业简历优化专家，请保持原始结构并优化内容细节"
                },
                {
                    "role": "user", 
                    "content": "请优化我的简历：",
                    "file_ids": [uploaded_file.id]
                }
            ]
        )
        optimized_text = completion.choices[0].message.content
        
        # 生成专业PDF
        generate_professional_pdf(optimized_text, optimized_path)
        
        # 添加后台清理任务
        background_tasks.add_task(cleanup_file, optimized_path)
        
        return FileResponse(
            str(optimized_path),  # Convert Path to string
            filename=output_filename,
            media_type="application/pdf"
        )
        
    except HTTPException as he:
        raise he
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"简历处理失败: {str(e)}"
        )
    finally:
        if temp_path.exists():
            temp_path.unlink()






@router.post("/chat", summary="AI聊天")
async def ai_chat(
    content: str,
    current_user: UserOccupied = Depends(get_current_user)
):
    """
    AI聊天接口
    
    权限要求:
    - 需要登录
    
    参数:
    - content: str, 用户输入的内容
    - current_user: UserOccupied, 当前登录用户信息
    
    返回:
    - AI生成的回复
    
    异常:
    - 500 Internal Server Error: 如果AI服务调用失败时抛出
    """
    try:
        client = OpenAI(api_key="sk-dutlhmfvsvrmxlgrygfaalxbconhzoyweakjvqsgtivtnkcb", base_url="https://api.siliconflow.cn/v1")
        
        completion = client.chat.completions.create(
            model="THUDM/GLM-4-32B-0414",
            messages=[
                {"role": "system", "content": "你是一个智能助手，请用专业且友好的方式回答用户问题。"},
                {"role": "user", "content": content}
            ],
            temperature=0.7,
            max_tokens=512,
            top_p=0.7
        )
        
        return {"response": completion.choices[0].message.content}
        
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"AI聊天失败: {str(e)}"
        )